/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cs575.coresystem;

import cs575.dbentities.Session;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

/**
 *
 * @author bms
 */
public class Authentication {

    private int userId;

    public Authentication(int user_id) {
        userId = user_id;
    }

    public Authentication() {
        userId = -1;
    }

    public Session authenticate(Session userSession) {
        Connection conn = null;
        Session ret = null;
        try {
            if (validate(userSession)) {
                Timestamp expireTime = null;
                conn = DBPool.getConnection();
                PreparedStatement state = conn.prepareStatement("SELECT user_id,expire_time FROM session WHERE session_key = ?");
                state.setString(1, userSession.getSessionKey());
                ResultSet result = state.executeQuery();
                if (result.next()) {
                    this.userId = result.getInt(1);
                    expireTime = result.getTimestamp(2);
                    // Check the expiration time
                    if (expireTime.after(Utils.dateFormat(new Date()))) {
                        ret = new Session(userId, userSession.getSessionKey(), expireTime);
                    }
                }
            }
        } catch (Exception e) {
        } finally {
            DBPool.closeConnection(conn);
        }
        return ret;
    }

    public Session authenticate(String username, String password) {
        Session userSession = null;
        Connection conn = null;
        try {
            conn = DBPool.getConnection();
            PreparedStatement state = conn.prepareStatement("SELECT user_id FROM user WHERE user_name = ? and password = ?");
            state.setString(1, username);
            state.setString(2, password);
            ResultSet result = state.executeQuery();
            if (result.next()) {
                int user_id = result.getInt(1);
                userSession = createSessionEntry(user_id);
            }
        } catch (Exception e) {
        } finally {
            DBPool.closeConnection(conn);
        }
        return userSession;
    }

    
    public Boolean endSession(Session session) {
        return deleteSessionEntry(session.getSessionKey());
    }

    private boolean validate(Session userSession) {
        if(userSession != null)
            return true;
        else
            return false;
    }

    private String getSessionKey(int user_id) {
        Connection conn = null;
        String session = null;
        try {
            conn = DBPool.getConnection();
            PreparedStatement state = conn.prepareStatement("SELECT session_key FROM session WHERE user_id = ?");
            state.setInt(1, user_id);
            ResultSet result = state.executeQuery();
            if (result.next()) {
                session = result.getString(1);
            }
        } catch (Exception e) {
        } finally {
            DBPool.closeConnection(conn);
        }
        return session;
    }

    private String generateSessionKey(int user_id) {
        return UUID.randomUUID().toString().replaceAll("[-]", "");
    }

    private Session createSessionEntry(int user_id) {
        Session userSession = null;
        Connection conn = null;
        try {
            // generate a new session key
            String tmpSession = generateSessionKey(user_id);
            // create a timestamp for the a week
            Calendar c = Calendar.getInstance();
            c.add(Calendar.DATE, 7);
            Timestamp time = Utils.dateFormat(c.getTime());

            conn = DBPool.getConnection();
            PreparedStatement state = conn.prepareStatement("INSERT ON DUPLICATE KEY UPDATE session SET session_key = ? and expire_time = ? where user_id = ?");
            state.setInt(3, user_id);
            state.setString(1, tmpSession);
            state.setTimestamp(2, time);
            int count = state.executeUpdate();
            if (count > 0) {
                userSession = new Session(user_id,tmpSession,time);
            }
        } catch (Exception e) {
        } finally {
            DBPool.closeConnection(conn);
        }
        return userSession;
    }

    private Boolean deleteSessionEntry(String session_key) {
        Boolean res = false;
        Connection conn = null;
        try {
            conn = DBPool.getConnection();
            PreparedStatement state = conn.prepareStatement("DELETE FROM session where session_key = ?");
            state.setString(1, session_key);
            state.executeUpdate();
            res = true;
        } catch (Exception e) {
        } finally {
            DBPool.closeConnection(conn);
        }
        return res;
    }
}
